Skip to content

WIP: feat: redesign invite and earn page#286

Closed
paolomolo wants to merge 4 commits intodevelopfrom
feat/invite-earn-page-redesign
Closed

WIP: feat: redesign invite and earn page#286
paolomolo wants to merge 4 commits intodevelopfrom
feat/invite-earn-page-redesign

Conversation

@paolomolo
Copy link
Copy Markdown
Contributor

@paolomolo paolomolo commented Nov 7, 2025

Note

Low Risk
Mostly UI/UX changes and new presentational components; minimal functional impact limited to client-side clipboard/social sharing and localStorage dismissal state.

Overview
Redesigns the Trendminer/Invite page into a richer “Invite & Earn” funnel with a new hero section, dismissible StepGuide, EarningExplanation (with a simple earnings calculator), and visualizations (EarningFlow, NetworkVisualization driven by current invite count).

Enhances the invite-link generation dialog with per-link copy buttons and sharing actions (Twitter intent, Discord copy, and optional native share), and refreshes CollectRewardsCard styling/CTA states with eligibility-driven visuals (e.g., progress/reward emphasis and animated particles). Adds a stubbed StatsSection (currently hidden behind showStats = false).

Written by Cursor Bugbot for commit 025e54e. This will update automatically on new commits. Configure here.

@netlify
Copy link
Copy Markdown

netlify bot commented Nov 7, 2025

Deploy Preview for fancy-gelato-7cdad5 ready!

Name Link
🔨 Latest commit 025e54e
🔍 Latest deploy log https://app.netlify.com/projects/fancy-gelato-7cdad5/deploys/69ccf867a095cf00084e2d42
😎 Deploy Preview https://deploy-preview-286--fancy-gelato-7cdad5.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

}, 200);

return () => clearInterval(interval);
}, [inviteCount]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Unnecessary animation wastes system resources.

The animation interval in NetworkVisualization continues running indefinitely even after all nodes are displayed. Once animatedNodes.length reaches nodes, the interval keeps firing every 200ms but only returns the same state, wasting CPU cycles. The interval should be cleared when animation completes.

Fix in Cursor Fix in Web

@paolomolo paolomolo force-pushed the feat/invite-earn-page-redesign branch from d924650 to a25fe6b Compare November 7, 2025 20:17
<stop offset="0%" stopColor="#ec4899" stopOpacity="0.5" />
<stop offset="100%" stopColor="#3b82f6" stopOpacity="0.5" />
</linearGradient>
</defs>
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Shared SVG Gradients Corrupt Visuals

SVG gradient IDs (centerGradient, nodeGradient, lineGradient) are hardcoded without uniqueness. If multiple NetworkVisualization components render on the same page, the gradient IDs will conflict, causing visual rendering issues where gradients from one instance affect others.

Fix in Cursor Fix in Web

<Share2 className="w-4 h-4" />
<span>Share</span>
</button>
)}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Graceful Handling for Share API Failures

Calling navigator.share() without error handling can throw exceptions if the user cancels the share dialog or if sharing fails. The unhandled promise rejection could cause console errors and poor user experience in production.

Fix in Cursor Fix in Web

@Andreea167
Copy link
Copy Markdown

Andreea167 commented Nov 11, 2025

Tested on PR -> the design looks great overall, just a few small notes to mentioned:

First of all, there is a bug opened for Revoke invites that are not displayed as revoked which would be nice to be resolved soon: #252

Additional gugs on Desktop & mobile:
1.button for connect wallet is "CONNECTWALLETTOGENERATE", please add space to be: "CONNECT WALLET TO GENERATE"
2.Alignment of the animated invite network diagram: the diagram overlaps with the invites count container

Mobile:
3. The inputs from "Try it yourself" and the input from generate invite link - "Number of invites" does not work as expected on mobile- you can not delete the value easily to choose another one (please see the video attached)

WhatsApp.Video.2025-11-11.at.12.19.05.mp4
  1. (low prio): rocket emoji and some green&purple animations are flashing too fast
WhatsApp.Video.2025-11-11.at.12.53.44.mp4

Also, one question: do we want the diagram to show all invitations as points, or just the ones claimed? -- because for example if I have 10 invitations, but I revoked 5, I think would be better to shown only 5 points as my network diagram, not all invites generated

- Redesigned hero section with bold headline emphasizing 0.5% earning potential

- Added interactive StepGuide component with expandable cards

- Created EarningExplanation component with interactive calculator

- Added EarningFlow visualization component

- Created NetworkVisualization component for invite network display

- Enhanced InviteAndEarnCard with social sharing buttons (Twitter, Discord)

- Enhanced CollectRewardsCard with celebration animations and better visuals

- Added StatsSection component (ready for API integration)

- Improved mobile responsiveness across all components

- Modern, engaging design targeting crypto-savvy users aged 18-25
- Replaced dark backgrounds with glass morphism using CSS variables

- Updated all cards to use bg-[var(--glass-bg)] and border-[var(--glass-border)]

- Applied backdrop-blur-[20px] and rounded-[20px] consistently

- Added hover effects with shadow and translate-y transitions

- Reduced opacity of gradient overlays for subtler glass effect

- Matches the liquid glass aesthetic used in feed items
- Update hero section text to 'Earn up to 0.5% of Every Token Purchase'

- Update commission rate stat to 'Up to 0.5%'

- Update InviteAndEarnCard description to 'Earn up to 0.5%'

- Update EarningFlow badge to 'Up to 0.5% Commission'

- Update EarningExplanation percentage display to 'Up to 0.5%'
- Remove AuroraBackground import from Invite.tsx

- Remove auroraConfig state and customization controls

- Remove AuroraBackground component usage from hero section
@CedrikNikita CedrikNikita force-pushed the feat/invite-earn-page-redesign branch from a25fe6b to 025e54e Compare April 1, 2026 10:50
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

Bugbot Autofix prepared fixes for all 3 issues found in the latest run.

  • ✅ Fixed: Unhandled navigator.share() promise rejection on cancel
    • Wrapped navigator.share() in async try/catch and ignore AbortError while logging other errors.
  • ✅ Fixed: Discord share button copies silently without user feedback
    • Discord button now calls copy with the row index so the checkmark feedback appears.
  • ✅ Fixed: Redundant useInvitations hook triggers duplicate API calls
    • Removed parent useInvitations call and derived invite count from the invitations atom to avoid extra fetches.

Create PR

Or push these changes by commenting:

@cursor push 684722b5bb
Preview (684722b5bb)
diff --git a/src/features/trending/components/Invitation/InviteAndEarnCard.tsx b/src/features/trending/components/Invitation/InviteAndEarnCard.tsx
--- a/src/features/trending/components/Invitation/InviteAndEarnCard.tsx
+++ b/src/features/trending/components/Invitation/InviteAndEarnCard.tsx
@@ -143,8 +143,9 @@
     window.open(`https://twitter.com/intent/tweet?text=${text}`, '_blank');
   };
 
-  const shareToDiscord = (link: string) => {
-    copyToClipboard(link, -1);
+  const shareToDiscord = (link: string, index: number) => {
+    // Provide visual feedback by using the row index (same as the copy button)
+    copyToClipboard(link, index);
   };
 
   const canUseNativeShare = typeof navigator !== 'undefined' && typeof navigator.share === 'function';
@@ -368,7 +369,7 @@
                     </button>
                     <button
                       type="button"
-                      onClick={() => shareToDiscord(link)}
+                      onClick={() => shareToDiscord(link, index)}
                       className="flex-1 min-w-[7rem] flex items-center justify-center gap-2 px-3 py-2 bg-[#5865F2]/20 hover:bg-[#5865F2]/30 border border-[#5865F2]/30 rounded-lg transition-all duration-300 text-sm text-white"
                     >
                       <MessageCircle className="w-4 h-4" />
@@ -377,7 +378,17 @@
                     {canUseNativeShare && (
                       <button
                         type="button"
-                        onClick={() => navigator.share({ text: link, title: 'Superhero Invite Link' })}
+                        onClick={async () => {
+                          try {
+                            await navigator.share({ text: link, title: 'Superhero Invite Link' });
+                          } catch (err: any) {
+                            // Swallow user-cancelled share; log other errors
+                            if (err?.name !== 'AbortError') {
+                              // eslint-disable-next-line no-console
+                              console.error('Share failed:', err);
+                            }
+                          }
+                        }}
                         className="flex-1 min-w-[7rem] flex items-center justify-center gap-2 px-3 py-2 bg-white/10 hover:bg-white/20 border border-white/20 rounded-lg transition-all duration-300 text-sm text-white"
                       >
                         <Share2 className="w-4 h-4" />

diff --git a/src/views/Trendminer/Invite.tsx b/src/views/Trendminer/Invite.tsx
--- a/src/views/Trendminer/Invite.tsx
+++ b/src/views/Trendminer/Invite.tsx
@@ -14,13 +14,14 @@
 } from '../../features/trending/components/Invitation';
 import Shell from '../../components/layout/Shell';
 import { useAeSdk } from '../../hooks';
-import { useInvitations } from '../../features/trending/hooks/useInvitations';
 import NetworkVisualization from '../../features/trending/components/Invitation/graphics/NetworkVisualization';
 import EarningFlow from '../../features/trending/components/Invitation/graphics/EarningFlow';
+import { useAtomValue } from 'jotai';
+import { invitationListAtom } from '../../atoms/invitationAtoms';
 
 export default function Invite() {
   const { activeAccount } = useAeSdk();
-  const { invitations } = useInvitations();
+  const invitationList = useAtomValue(invitationListAtom);
   const [showStepGuide, setShowStepGuide] = useState<boolean>(() => {
     try {
       if (localStorage.getItem('invite_step_guide_dismissed') === '1') return false;
@@ -39,7 +40,9 @@
     setShowStepGuide(false);
   };
 
-  const inviteCount = invitations?.length || 0;
+  const inviteCount = activeAccount
+    ? invitationList.filter(({ inviter }) => inviter === activeAccount).length
+    : 0;
 
   return (
     <Shell>

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

{canUseNativeShare && (
<button
type="button"
onClick={() => navigator.share({ text: link, title: 'Superhero Invite Link' })}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unhandled navigator.share() promise rejection on cancel

Medium Severity

The navigator.share() call returns a Promise that isn't caught. When users dismiss the native share dialog, it rejects with an AbortError, producing an unhandled promise rejection. Compare with copyToClipboard which correctly wraps navigator.clipboard.writeText in a try/catch — the same error handling pattern is missing here.

Fix in Cursor Fix in Web


const shareToDiscord = (link: string) => {
copyToClipboard(link, -1);
};
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discord share button copies silently without user feedback

Medium Severity

shareToDiscord calls copyToClipboard(link, -1) which copies to clipboard but passes index -1. Since the checkmark feedback UI only checks copiedLinkIndex === index for non-negative indices, users see no visual confirmation that anything happened. Unlike shareToTwitter which opens Twitter, this button labeled "Discord" silently copies with no feedback — a confusing inconsistency.

Fix in Cursor Fix in Web

export default function Invite() {
const { activeAccount } = useAeSdk();
const [showInfo, setShowInfo] = useState<boolean>(() => {
const { invitations } = useInvitations();
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Redundant useInvitations hook triggers duplicate API calls

Low Severity

Invite.tsx now calls useInvitations() solely for invitations.length, but child components InviteAndEarnCard and InvitationList already call the same hook. Since transactionList is local state (not shared via atoms), each instance independently fetches the same transaction data from the middleware API, tripling the network requests on every account change or refresh.

Fix in Cursor Fix in Web

@CedrikNikita CedrikNikita deleted the feat/invite-earn-page-redesign branch April 1, 2026 11:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants